package com.itheima.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
/*使用配置文件*/
//通知类，告诉spring在增强的前后需要做什么事
public class Advice {

    /**
     * spring在调用该方法时会把正在运行的方法传递给外面
     * @param joinPoint :封装了正在运行的方法
     *      注意 :该方法是这个包下的 :import org.aspectj.lang.JoinPoint;
     */
    public void before(JoinPoint joinPoint){
        //在前置对象中, 获取方法中的参数(不能在这里获得结果, 因为方法都没运行.)
        Object[] args = joinPoint.getArgs();
        System.out.println(args);

        //前置通知：开启事务
        System.out.println("前置通知：开启事务");
    }
    public void afterReturn(Object ret){
        //获取目标方法的结果/返回值(要在配置文件中进行配置)

        //后置通知：提交事务
        System.out.println("后置通知：提交事务");
    }
    public void afterThrowable(Throwable err){
        //异常通知：回滚事务
        System.out.println("异常通知：回滚事务");
    }
    public void after(){
        //最终通知：释放资源
        System.out.println("最终通知：释放资源");
    }

    /**
     * 环绕通知 :是Spring给我们提供的一种手动调用目标对象方法或者其他通知方法的通知方式(可以代替上面的4种通知)
     * @param pjp  :ProceedingJoinPoint pjp :正在执行的连接点, 也就是连接到的被代理对象的方法
     * @return
     * 注意 :需要在配置文件中进行配置
     *
     * 这里可以获得所有(获取目标方法参数; 获取目标方法运行的结果/返回值; 获取异常通知)
     */
    public Object around(ProceedingJoinPoint pjp){
        Object proceed = null;
        try {
            //前置通知
           //before();
            //获取拦截的被代理对象的方法中的参数
            Object[] args = pjp.getArgs();
            //执行被代理对象原方法
            proceed = pjp.proceed(args); //这里获取的是目标方法运行后的结果/返回值
            //后置通知
            //afterReturn();
        } catch (Throwable throwable) {//获取异常通知
            throwable.printStackTrace();
            //异常通知
           // afterThrowable();
        } finally {
            //最终通知
            after();
        }
        return proceed;

    }
}
